import daemon
import redis
import json
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
from dateutil.relativedelta import relativedelta
from datetime import datetime,timedelta
import psycopg2
import time
import os


def qhdm_2_tiles(cargs,qhdm):
    connection = psycopg2.connect(**cargs)
    connection.autocommit = True
    cursor = connection.cursor()
    # query = f"""
    #         SELECT distinct china_tile.tile
    #         FROM china_tile
    #         JOIN dt_sy 
    #         on st_intersects(china_tile.geom,dt_sy.shape)
    #         WHERE dt_sy.qhdm = '{qhdm}' 
    #         """
    query = f"""
            SELECT distinct tile
            FROM qh_tile
            WHERE qhdm = '{qhdm}' 
            """
    try:
        cursor.execute(query)
        connection.commit()
        data = cursor.fetchall()
    except Exception as e:
        connection.rollback()
    cursor.close()
    connection.close()
    return [i[0] for i in data] 


def split_periods(period):
    start_date,end_date = period
    start_date = datetime.strptime(start_date,"%Y-%m-%d")
    end_date = datetime.strptime(end_date,"%Y-%m-%d")
    split_date = datetime.now()-timedelta(days=5)
    if start_date <= split_date <= end_date:
        history_period = (
            start_date.strftime("%Y-%m-%d"), split_date.strftime("%Y-%m-%d"))
        current_period = (
            split_date.strftime("%Y-%m-%d"), end_date.strftime("%Y-%m-%d"))
    elif end_date < split_date:
        history_period = (
            start_date.strftime("%Y-%m-%d"), split_date.strftime("%Y-%m-%d"))
        current_period = None
    elif split_date < start_date :
        history_period = None
        current_period = (
            split_date.strftime("%Y-%m-%d"), end_date.strftime("%Y-%m-%d"))
    else:
        raise("输入日期有误！")
    return history_period,current_period


def get_request_args(tile,period,cloud):
    start, end = period
    url = "https://catalogue.dataspace.copernicus.eu/odata/v1/Products"
    attributes = [
        f"Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'tileId' and att/OData.CSC.StringAttribute/Value eq '{tile}')",
        f"Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'processingLevel' and att/OData.CSC.StringAttribute/Value eq 'S2MSI1C')",#S2MSI1C
        f"Attributes/OData.CSC.DoubleAttribute/any(att:att/Name eq 'cloudCover' and att/OData.CSC.DoubleAttribute/Value lt {cloud})",
        f"ContentDate/Start gt {start}T00:00:00.000Z",
        f"ContentDate/Start lt {end}T00:00:00.000Z"]
    params = {
        '$filter':" and ".join(attributes),
        '$orderby': "ContentDate/Start desc",
        '$count':'True',
        '$expand': 'Attributes'} # Assets Attributes
    return (tile,url,params)


def execute_histroy(tiles,historyp,cloud,loading_queue,logger):
    if historyp: # 若历史时期存在，则执行立即查询、更新表、加载任务
        for tile in tiles:
            logger.info(f"loading:{tile} {historyp} {cloud}")
            item = get_request_args(tile,historyp,cloud)
            loading_queue.put(item)
    return


def execute_current(tiles,currentp,cloud,interval,loading_queue,logger):
    if currentp: # 如果近期存在，则执行定时查询、更新表、加载任务
        start_date, end_date = currentp
        start_date = datetime.strptime(start_date,"%Y-%m-%d")
        end_date = datetime.strptime(end_date,"%Y-%m-%d")
        while start_date > datetime.now():
            logger.info('开始日期在今天之后，等待1小时为周期')
            time.sleep(60*60)
        while datetime.now() <= end_date + timedelta(days=5): # 今天小于执行结束日期，可执行
            if datetime.now()-timedelta(days=5) > start_date: # 若开始日期在前五天之前，开始日期重置为前五天
                sdate = datetime.now()-timedelta(days=5) 
            else:
                sdate = start_date
            if end_date > datetime.now(): # 若结束日期在今天之后，结束日期重置为明天
                edate = datetime.now()+timedelta(days=1)
            else:
                edate = end_date
            cperiod = (sdate.strftime("%Y-%m-%d"),edate.strftime("%Y-%m-%d"))
            for tile in tiles:
                logger.info(f"loading:{tile} {cperiod} {cloud}")
                item = get_request_args(tile,cperiod,cloud)
                loading_queue.put(item)
            logger.info("开始以8小时为周期的休眠！")
            time.sleep(interval)  # 8小时为周期
    return


def main(qhdm,period,cloud:int = 100):
    with open('/data/fengyy/project/CopernicusSentinel2Level1C/main/config.json',"r") as file:
        params = json.load(file)
    cargs = params["cargs"]
    interval = params['interval']
    rediscon = params["rediscon"]
    pool = redis.ConnectionPool(**rediscon)
    redisr = redis.Redis(connection_pool=pool)
    tiles = qhdm_2_tiles(cargs,qhdm)
    historyp, currentp = split_periods(period)
    
    if historyp: # 若历史时期存在，则执行立即查询、更新表、加载任务
        for tile in tiles:
            print(f"loading:{tile} {historyp} {cloud}")
            item = get_request_args(tile,historyp,cloud)
            redisr.lpush('loader_searcher', json.dumps(list(item)))
            
    if currentp: # 如果近期存在，则执行定时查询、更新表、加载任务
        start_date, end_date = currentp
        start_date = datetime.strptime(start_date,"%Y-%m-%d")
        end_date = datetime.strptime(end_date,"%Y-%m-%d")
        while start_date > datetime.now():
            print('开始日期在今天之后，等待1小时为周期')
            time.sleep(60*60)
        while datetime.now() <= end_date + timedelta(days=5): # 今天小于执行结束日期，可执行
            if datetime.now()-timedelta(days=5) > start_date: # 若开始日期在前五天之前，开始日期重置为前五天
                sdate = datetime.now()-timedelta(days=5) 
            else:
                sdate = start_date
            if end_date > datetime.now(): # 若结束日期在今天之后，结束日期重置为明天
                edate = datetime.now()+timedelta(days=1)
            else:
                edate = end_date
            cperiod = (sdate.strftime("%Y-%m-%d"),edate.strftime("%Y-%m-%d"))
            for tile in tiles:
                print(f"loading:{tile} {cperiod} {cloud}")
                item = get_request_args(tile,cperiod,cloud)
                redisr.rpush('loader_searcher', json.dumps(list(item)))
            print("开始以8小时为周期的休眠！")
            time.sleep(interval)  # 8小时为周期      
    redisr.rpush('loader_searcher','None')
    print("加载结束！")
    return


def run_daemon():
    qhdm = '41'
    period = ['2024-04-01', '2024-06-01']
    with daemon.DaemonContext(
        stdout=open(r"/data/fengyy/logfile/coperni_LoaderDaemon.py.log","w"),
        stderr=open(r"/data/fengyy/logfile/coperni_LoaderDaemon.py.log","w")
        ):
        main(qhdm,period)
    return


if __name__ == "__main__":
    run_daemon()
    # qhdm = '41'
    # period = ['2024-04-01', '2024-06-01']
    # main(qhdm,period)